Tehnical Indicator

We will implement several technical indicatiors using pandas


In [1]:
%matplotlib inline

In [2]:
# Make the plots larger
from IPython.core.pylabtools import figsize
figsize(15, 5)

In [3]:
import pandas as pd

Getting stock prices

Where can we get the stock prices data to do analysis? Easy, pandas has built-in method to extract data from

  • Yahoo! Finance
  • Google Finance
  • St. Louis FED (FRED)
  • Kenneth French’s data library
  • World Bank

In [4]:
import pandas.io.data as web

Get HSBC stock qoute during 2008 - 2013 from Yahoo! Finance


In [5]:
web.DataReader('0005.HK', 'yahoo', start='2008-01-01', end='2013-12-31').head()


Out[5]:
Open High Low Close Volume Adj Close
Date
2008-01-01 131.7 131.7 131.7 131.7 0 126.77
2008-01-02 131.5 131.9 130.2 130.9 11105600 126.00
2008-01-03 129.8 130.5 129.2 129.6 17407500 124.75
2008-01-04 129.4 131.2 129.4 130.1 16285700 125.23
2008-01-07 128.4 128.4 127.1 127.9 31510500 123.12

5 rows × 6 columns

There is a short cut...


In [6]:
hsbc = web.get_data_yahoo('0005.HK', start='2008-01-01', end='2013-12-31')
hsbc.head()


Out[6]:
Open High Low Close Volume Adj Close
Date
2008-01-01 131.7 131.7 131.7 131.7 0 126.77
2008-01-02 131.5 131.9 130.2 130.9 11105600 126.00
2008-01-03 129.8 130.5 129.2 129.6 17407500 124.75
2008-01-04 129.4 131.2 129.4 130.1 16285700 125.23
2008-01-07 128.4 128.4 127.1 127.9 31510500 123.12

5 rows × 6 columns

The Yahoo! Finace data has data for every weekdays, which includes public hoildays...


In [7]:
hsbc[hsbc['Volume'] == 0].head()


Out[7]:
Open High Low Close Volume Adj Close
Date
2008-01-01 131.7 131.7 131.7 131.7 0 126.77
2008-02-07 114.0 114.0 114.0 114.0 0 109.74
2008-02-08 114.0 114.0 114.0 114.0 0 109.74
2008-03-21 121.0 121.0 121.0 121.0 0 116.85
2008-03-24 121.0 121.0 121.0 121.0 0 116.85

5 rows × 6 columns

To clean up the data, we excludes those data with 0 volume


In [8]:
hsbc = hsbc[hsbc['Volume'] != 0]
hsbc.head()


Out[8]:
Open High Low Close Volume Adj Close
Date
2008-01-02 131.5 131.9 130.2 130.9 11105600 126.00
2008-01-03 129.8 130.5 129.2 129.6 17407500 124.75
2008-01-04 129.4 131.2 129.4 130.1 16285700 125.23
2008-01-07 128.4 128.4 127.1 127.9 31510500 123.12
2008-01-08 128.1 129.8 128.1 128.3 17526900 123.50

5 rows × 6 columns

Again, plot is much easier to understand


In [9]:
hsbc.plot(secondary_y='Volume')


Out[9]:
<matplotlib.axes.AxesSubplot at 0x7fd17bb1fc10>

In here, we are only interested in adjusted close


In [10]:
hsbc = hsbc['Adj Close']
hsbc.name = '0005.HK'
hsbc.plot()


Out[10]:
<matplotlib.axes.AxesSubplot at 0x7fd17ba87450>

Simple statistics of a stock

Returns of HSBC


In [11]:
hsbc.pct_change().head()


Out[11]:
Date
2008-01-02         NaN
2008-01-03   -0.009921
2008-01-04    0.003848
2008-01-07   -0.016849
2008-01-08    0.003086
Name: 0005.HK, dtype: float64

Drop the NaN in the first period


In [12]:
hsbc_ret = hsbc.pct_change().dropna()
hsbc_ret.head()


Out[12]:
Date
2008-01-03   -0.009921
2008-01-04    0.003848
2008-01-07   -0.016849
2008-01-08    0.003086
2008-01-09   -0.002348
Name: 0005.HK, dtype: float64

Average return


In [13]:
hsbc_ret.mean()


Out[13]:
-2.0154234215377223e-05

Volatility


In [14]:
hsbc_ret.std()


Out[14]:
0.022410959622619426

Density


In [15]:
hsbc_ret.plot(kind='kde')


Out[15]:
<matplotlib.axes.AxesSubplot at 0x7fd17b080550>

Cummulative Return


In [16]:
(hsbc_ret + 1).prod() - 1


Out[16]:
-0.33380952380952533

Rolling statistics

Many technical indicators are making use of moving average. Pandas has a number of rolling statistics built-in.

  • rolling_count
  • rolling_sum
  • rolling_mean
  • rolling_median
  • rolling_min
  • rolling_max
  • rolling_std
  • rolling_var
  • rolling_skew
  • rolling_kurt
  • rolling_quantile
  • rolling_apply
  • rolling_cov
  • rolling_corr
  • rolling_window

Simple Moving Average (SMA)


In [17]:
hsbc_sma = pd.DataFrame({'Price': hsbc})
hsbc_sma['5 Day SMA'] = pd.rolling_mean(hsbc, window=5)
hsbc_sma['20 Day SMA'] = pd.rolling_mean(hsbc, window=20)
hsbc_sma['250 Day SMA'] = pd.rolling_mean(hsbc, window=250)
hsbc_sma


Out[17]:
Price 5 Day SMA 20 Day SMA 250 Day SMA
Date
2008-01-02 126.00 NaN NaN NaN
2008-01-03 124.75 NaN NaN NaN
2008-01-04 125.23 NaN NaN NaN
2008-01-07 123.12 NaN NaN NaN
2008-01-08 123.50 124.520 NaN NaN
2008-01-09 123.21 123.962 NaN NaN
2008-01-10 121.58 123.328 NaN NaN
2008-01-11 118.98 122.078 NaN NaN
2008-01-14 118.88 121.230 NaN NaN
2008-01-15 116.28 119.786 NaN NaN
2008-01-16 110.70 117.284 NaN NaN
2008-01-17 114.45 115.858 NaN NaN
2008-01-18 113.97 114.856 NaN NaN
2008-01-21 109.54 112.988 NaN NaN
2008-01-22 100.40 109.812 NaN NaN
2008-01-23 111.66 110.004 NaN NaN
2008-01-24 111.28 109.370 NaN NaN
2008-01-25 116.47 109.870 NaN NaN
2008-01-28 112.14 110.390 NaN NaN
2008-01-29 113.30 112.970 116.7720 NaN
2008-01-30 112.91 113.220 116.1175 NaN
2008-01-31 111.28 113.220 115.4440 NaN
2008-02-01 113.78 112.682 114.8715 NaN
2008-02-04 116.18 113.490 114.5245 NaN
2008-02-05 114.55 113.740 114.0770 NaN
2008-02-06 109.74 113.106 113.4035 NaN
2008-02-11 105.31 111.912 112.5900 NaN
2008-02-12 106.27 110.410 111.9545 NaN
2008-02-13 108.20 108.814 111.4205 NaN
2008-02-14 111.85 108.274 111.1990 NaN
2008-02-15 110.22 108.370 111.1750 NaN
2008-02-18 108.39 108.986 110.8720 NaN
2008-02-19 110.02 109.736 110.6745 NaN
2008-02-20 108.68 109.832 110.6315 NaN
2008-02-21 109.83 109.428 111.1030 NaN
2008-02-22 110.51 109.486 111.0455 NaN
2008-02-25 112.33 110.274 111.0980 NaN
2008-02-26 115.22 111.314 111.0355 NaN
2008-02-27 118.98 113.374 111.3775 NaN
2008-02-28 118.40 115.088 111.6325 NaN
2008-02-29 116.18 116.222 111.7960 NaN
2008-03-03 114.64 116.684 111.9640 NaN
2008-03-04 115.90 116.820 112.0700 NaN
2008-03-05 116.18 116.260 112.0700 NaN
2008-03-06 116.86 115.952 112.1855 NaN
2008-03-07 112.82 115.280 112.3395 NaN
2008-03-10 116.28 115.608 112.8880 NaN
2008-03-11 118.11 116.050 113.4800 NaN
2008-03-12 120.71 116.956 114.1055 NaN
2008-03-13 117.82 117.148 114.4040 NaN
2008-03-14 118.21 118.226 114.8035 NaN
2008-03-17 113.59 117.688 115.0635 NaN
2008-03-18 115.90 117.246 115.3575 NaN
2008-03-19 117.72 116.648 115.8095 NaN
2008-03-20 116.85 116.454 116.1605 NaN
2008-03-25 122.45 117.302 116.7575 NaN
2008-03-26 122.94 119.172 117.2880 NaN
2008-03-27 123.03 120.598 117.6785 NaN
2008-03-28 123.61 121.776 117.9100 NaN
2008-03-31 122.45 122.896 118.1125 NaN
... ... ... ...

1479 rows × 4 columns


In [18]:
hsbc_sma.plot()


Out[18]:
<matplotlib.axes.AxesSubplot at 0x7fd170147ed0>

In [19]:
hsbc_sma[-90:].plot()


Out[19]:
<matplotlib.axes.AxesSubplot at 0x7fd1700f4090>

Exponential Moving Average (EMA)


In [20]:
hsbc_ema = pd.DataFrame({'Price': hsbc})
hsbc_ema['5 Day EMA'] = pd.ewma(hsbc, span=5)
hsbc_ema['20 Day EMA'] = pd.ewma(hsbc, span=20)
hsbc_ema['250 Day EMA'] = pd.ewma(hsbc, span=250)
hsbc_ema.plot()


Out[20]:
<matplotlib.axes.AxesSubplot at 0x7fd17007bb50>

In [21]:
hsbc_ema[-90:].plot()


Out[21]:
<matplotlib.axes.AxesSubplot at 0x7fd16bad8cd0>

In [22]:
hsbc_px_ret_vol = pd.DataFrame({'Price': hsbc, 'Returns': hsbc_ret})
hsbc_px_ret_vol['5 Day Vol'] = pd.rolling_std(hsbc_ret, window=5)
hsbc_px_ret_vol.plot(subplots=True)


Out[22]:
array([<matplotlib.axes.AxesSubplot object at 0x7fd16b9eba10>,
       <matplotlib.axes.AxesSubplot object at 0x7fd16b92c990>,
       <matplotlib.axes.AxesSubplot object at 0x7fd16b8fc190>], dtype=object)

In [23]:
hsbc_px_ret_vol.plot(kind='scatter', x='Returns', y='5 Day Vol')


Out[23]:
<matplotlib.axes.AxesSubplot at 0x7fd16b8e4450>

In [24]:
hsbc_px_ret_vol[['Returns', '5 Day Vol']].corr()


Out[24]:
Returns 5 Day Vol
Returns 1.000000 0.044181
5 Day Vol 0.044181 1.000000

2 rows × 2 columns